using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using Athena.SBW;

namespace Athena.Plugins
{
    public partial class SimulationControlOptions : WeifenLuo.WinFormsUI.Docking.DockContent
    {
        private const string STR_NodeBoundary = "nodeBoundary";
        private const string STR_NodeBoundary_Label = "Boundary Species";
        private const string STR_NodeParameters = "nodeParameters";
        private const string STR_NodeParameters_Label = "Parameters";
        private const string STR_Floating = "oFloating";
        private const string STR_Fluxes = "oFluxes";
        private const string STR_Rates = "oRates";

        private SimulationControl _oSimulationControl;
        public SimulationControl SimulationControl
        {
            get
            {
                return _oSimulationControl;
            }
            set
            {
            	 _oSimulationControl = value;
            }
        }

        public SimulationControlOptions(SimulationControl oControl)
        {
            InitializeComponent();

            // initialize groups
            TreeNode oGroupBoundary = new TreeNode(STR_NodeBoundary_Label);
            TreeNode oGroupParameter = new TreeNode(STR_NodeParameters_Label);
            
            oGroupBoundary.Name = STR_NodeBoundary; 
            oGroupBoundary.Text = STR_NodeBoundary_Label;
            oGroupParameter.Name = STR_NodeParameters;
            oGroupParameter.Text = STR_NodeParameters_Label;
            this.treeSliders.Nodes.AddRange(new TreeNode[] {
                    oGroupBoundary,oGroupParameter});


            _oSimulationControl = oControl;

            VisibleChanged += new EventHandler(SimulationControlOptions_VisibleChanged);
        }

        void SimulationControlOptions_VisibleChanged(object sender, EventArgs e)
        {
            PopulateListBox();
            InitializeOutputPanel();
        }

        protected override bool ProcessDialogKey(Keys keyData)
        {
            switch (keyData)
            {
                case Keys.Left:
                case Keys.Right:
                    return false;
                default:
                    break;
            }
            return base.ProcessDialogKey(keyData);
        }

        /// <summary>
        /// get or set the simulator to use
        /// </summary>
        public Simulator Simulator
        {
            get { return ToolManager.Instance.Simulator; }
            set { ToolManager.Instance.Simulator = value; }
        }

        /// <summary>
        /// get or set the analyzer to use. The Analyzer plots the rate functions and 
        /// the vector fields
        /// </summary>
        public Analyzer Analyzer
        {
            get { return ToolManager.Instance.Analyzer; }
            set { ToolManager.Instance.Analyzer = value; }
        }


        private void cmdPopulate_Click(object sender, EventArgs e)
        {
            PopulateListBox();
        }

        private void FillGroup(string sGroup, ArrayList oNames, double[] oValues)
        {
            treeSliders.Nodes[sGroup].Nodes.Clear();
            for (int i = 0; i < oNames.Count; i++)
            {
                SliderTreeViewNode oNode = new SliderTreeViewNode(
                    _oSimulationControl, 
                    Simulator,
                    Analyzer,
                    (string)oNames[i],
                    oValues[i]
                    );

                treeSliders.Nodes[sGroup].Nodes.Add(oNode);
            }
        }

        private void PopulateListBox()
        {
            if (Simulator == null) return;
            if (!Simulator.HasModel) return;
            
            treeSliders.HideSliderControl();

            if (_oSimulationControl != null)
                _oSimulationControl.EnableUpdating = false;

            ArrayList oBoundary = Simulator.getBoundarySpeciesNames();
            double[] oValues = Simulator.getBoundarySpeciesConcentration();

            FillGroup(STR_NodeBoundary, oBoundary, oValues);

            ArrayList oParams = Simulator.getGlobalParameterNames();
            double[] dParamValues = Simulator.getGlobalParameterValues();

            FillGroup(STR_NodeParameters, oParams, dParamValues);

            if (_oSimulationControl != null)
                _oSimulationControl.EnableUpdating = true;

        }

        private void cmdCancel_Click(object sender, EventArgs e)
        {
            this.Hide();
        }

        private void cmdOK_Click(object sender, EventArgs e)
        {
            ArrayList oList = GetSelectionList();
            if (Simulator != null && Simulator.HasModel)
                Simulator.setSelectionList(oList);

            _oSimulationControl.InitializeSimulationColumns();
            _oSimulationControl.UpdateSimulationResults(true);            
            this.Hide();
        }

        private void oOutputPopulate_Click(object sender, EventArgs e)
        {
            InitializeOutputPanel();
        }

        private void InitializeOutputPanel()
        {
            treeAvailableOutput.Nodes.Clear();
            lstSelectedOutput.Items.Clear();

            if (Simulator == null || !Simulator.HasModel)
                return;


            ArrayList oAvailable = _oSimulationControl.SimulatorAvailableList();
            ArrayList oSelected = _oSimulationControl.SimulatorSelectionList();

            foreach (ArrayList list in oAvailable)
            {

                string sName = (string)list[0];
                ArrayList oItems = (ArrayList)list[1];

                TreeNode oGroup = new TreeNode(sName);
                oGroup.Tag = "group";

                foreach (string s in oItems)
                {
                    TreeNode oNode = new TreeNode(s);
                    oNode.Tag = "item";
                    oGroup.Nodes.Add(oNode);
                }

                treeAvailableOutput.Nodes.Add(oGroup);

            }

            foreach (string s in oSelected)
            {
                lstSelectedOutput.Items.Add(s);
            }

        }

        private void cmdRemoveOutput_Click(object sender, EventArgs e)
        {
            RemoveSelected();
        }

        private void cmdAddOutput_Click(object sender, EventArgs e)
        {
            AddSelected();
        }

        private void cmdClearOutput_Click(object sender, EventArgs e)
        {
            lstSelectedOutput.Items.Clear();
        }

        private void AddSelected()
        {
            TreeNode oSelected = treeAvailableOutput.SelectedNode;
            if (oSelected != null && oSelected.Tag != null && oSelected.Tag is string)
            {
                switch (oSelected.Tag as string)
                {
                    case "item":
                        AddItem(oSelected.Text);
                        break;
                    case "group":
                        foreach (TreeNode node in oSelected.Nodes)
                        {
                            AddItem(node.Text);
                        }
                        break;
                    default:
                        break;
                }
            }
        }
        private void treeAvailableOutput_DoubleClick(object sender, EventArgs e)
        {
            AddSelected();
        }

        private void AddItem(string sItem)
        {

            if (!lstSelectedOutput.Items.Contains(sItem))
            {
                lstSelectedOutput.Items.Add(sItem);
            }

        }

        private void RemoveSelected()
        {
            if (lstSelectedOutput.SelectedItem != null)
                lstSelectedOutput.Items.Remove(lstSelectedOutput.SelectedItem);
        }
        private void lstSelectedOutput_DoubleClick(object sender, EventArgs e)
        {
            RemoveSelected();
        }

        private ArrayList GetSelectionList()
        {
            ArrayList oList = new ArrayList();
            foreach (string s in lstSelectedOutput.Items)
            {
                oList.Add(s);
            }
            return oList;
        }
        private void cmdSetSelectionList_Click(object sender, EventArgs e)
        {
            ArrayList oList = GetSelectionList();
            if (Simulator != null && Simulator.HasModel)
                Simulator.setSelectionList(oList);

            _oSimulationControl.InitializeSimulationColumns();
            _oSimulationControl.UpdateSimulationResults(true);
        }

        public ArrayList SelectionList
        {
            get { return GetSelectionList(); }            
        }





  


     
    }
}

